/**
 * @file Bsp_Key.c
 * @author 徐松亮 (5387603@qq.com)
 * @version 1.0
 * @date 2023-09-28
 *
 * @copyright Copyright (c) {2030}  沈阳迈思医疗科技有限公司
 *
 * @brief 驱动层-->基于GPIO的按键驱动(包含多种驱动方式)
 */
//------------------------------- Includes --------------------
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "Bsp_Key.h"
#include "Module_MemManager.h"
/* 编译警告条件 (Compile warning condition)------------------------------------*/
/* 私有类型定义 (Private typedef)----------------------------------------------*/
/* 私有型宏定义 (Private define)-----------------------------------------------*/
/* 私有常量定义 (Private constants)--------------------------------------------*/
/* 公有常量定义 (Public constants)---------------------------------------------*/
/* 私有变量定义 (Private variables)--------------------------------------------*/
/* 公有变量定义 (Public variables)---------------------------------------------*/
/* 私有函数声明 (Private function prototypes)----------------------------------*/
static void BspKey_Cycle_10ms(void *_tp_interface);
static void BspKey_Cycle_1000ms(void *_tp_interface);
/* 私有函数实体 (Private functions)--------------------------------------------*/
/**
 * @brief
 * @param[in]  _tp_interfaceMy Param doc
 */
static void BspKey_Cycle_10ms(void *_tp_interface)
{
    BSP_KEY_T_INTERFACE *tp_interface = _tp_interface;
    if (tp_interface->t_Input.fnp_PressCondition() == true)
    {
        tp_interface->t_Output.uc_RealValue = true;
        if (tp_interface->t_Output.us_PressedKeepTimer_ms < 60000)
        {
            tp_interface->t_Output.us_PressedKeepTimer_ms += 10;
        }
    }
    else
    {
        tp_interface->t_Output.uc_RealValue = false;
        tp_interface->t_Output.us_PressedKeepTimer_ms = 0;
    }
    //
    switch (tp_interface->t_Private.uc_ProcessStep)
    {
    case 0: // 初始化
        if (tp_interface->t_Output.uc_RealValue != false)
        {
            tp_interface->t_Private.uc_ProcessKeyValueBak = tp_interface->t_Output.uc_RealValue;
            tp_interface->t_Private.uc_ProcessCmt = 0;
            tp_interface->t_Private.uc_ProcessStep = 1;
        }
        break;
    case 1:
        if (++(tp_interface->t_Private.uc_ProcessCmt) > 2)
        {
            if (tp_interface->t_Private.uc_ProcessKeyValueBak == tp_interface->t_Output.uc_RealValue)
            {
                tp_interface->t_Private.uc_ProcessStep = 2;
                tp_interface->t_Private.uc_ProcessPressedFlag = 1;
            }
            else
            {
                tp_interface->t_Private.uc_ProcessKeyValueBak = 0;
                tp_interface->t_Private.uc_ProcessStep = 0;
            }
        }
        else
        {
            if (tp_interface->t_Private.uc_ProcessKeyValueBak != tp_interface->t_Output.uc_RealValue)
            {
                tp_interface->t_Private.uc_ProcessKeyValueBak = 0;
                tp_interface->t_Private.uc_ProcessStep = 0;
            }
        }
        break;
    case 2: // 等待新键处理完毕
        tp_interface->t_Output.us_PressedKeepTime_ms = 0;
        tp_interface->t_Private.uc_ProcessStep = 3;
        break;
    case 3: // 等待见放开
        if (tp_interface->t_Output.uc_RealValue == false)
        {
            tp_interface->t_Private.uc_ProcessStep = 4;
            tp_interface->t_Private.uc_ProcessCmt = 0;
        }
        else if (tp_interface->t_Output.uc_RealValue == tp_interface->t_Private.uc_ProcessKeyValueBak)
        {
            tp_interface->t_Output.us_PressedKeepTime_ms += 10;
        }
        else
        {
            tp_interface->t_Private.uc_ProcessKeyValueBak = 0;
            tp_interface->t_Private.uc_ProcessStep = 0;
        }
        break;
    case 4: // 放键去抖
        if (++(tp_interface->t_Private.uc_ProcessCmt) > 5)
        {
            if (tp_interface->t_Output.uc_RealValue != false)
            {
                tp_interface->t_Private.uc_ProcessCmt = 0;
            }
            else
            {
                tp_interface->t_Private.uc_ProcessStep = 0;
                tp_interface->t_Private.uc_ProcessCmt = 0;
                tp_interface->t_Private.uc_ProcessKeyValueBak = 0;
            }
        }
        break;
    default:
        tp_interface->t_Private.uc_ProcessStep = 0;
        tp_interface->t_Private.uc_ProcessCmt = 0;
        tp_interface->t_Private.uc_ProcessKeyValueBak = 0;
        break;
    }
    //
    if (tp_interface->t_Private.uc_ProcessPressedFlag == 1 && tp_interface->t_Private.uc_ProcessStep == 0)
    {
        tp_interface->t_Private.uc_ProcessPressedFlag = 0;
        //
        tp_interface->t_Output.uc_Flag_Pressed = 1;
        //
        if (tp_interface->t_Output.us_PressedCmt != 0xFFFF)
        {
            tp_interface->t_Output.us_PressedCmt++;
        }
        else
        {
            tp_interface->t_Output.us_PressedCmt = 0;
        }
    }
}
/**
 * @brief
 * @param[in]  _tp_interfaceMy Param doc
 */
static void BspKey_Cycle_1000ms(void *_tp_interface)
{
    char *pbuf = NULL;
    BSP_KEY_T_INTERFACE *tp_interface = _tp_interface;
    if (tp_interface->t_Private.uc_DebugTestEnable == 1)
    {
        // 申请缓存
        pbuf = ModuleMemManager_Get(E_MEM_MANAGER_TYPE_256B);
        sprintf(pbuf, "DebugOut: Count-%d,Key=%d\r\n",
                tp_interface->t_Output.us_PressedCmt, tp_interface->t_Output.uc_RealValue);
        tp_interface->t_Input.fnp_DebugOutStr((int8_t *)pbuf);
        // 释放缓存
        ModuleMemManager_Free(E_MEM_MANAGER_TYPE_256B, pbuf);
    }
}
/* 公有函数实体 (Public functions)---------------------------------------------*/
/**
 * @brief
 * @param[in]  _tp_interfaceMy Param doc
 */
void BspKey_Init(BSP_KEY_T_INTERFACE *_tp_interface)
{
    _tp_interface->t_Transplant.fnp_Cycle_10ms = BspKey_Cycle_10ms;
    _tp_interface->t_Transplant.fnp_Cycle_1000ms = BspKey_Cycle_1000ms;
}
/**
 * @brief
 * @param[in]  _uc_trueOrFalse        My Param doc
 * @param[in]  _vp_context   My Param doc
 */
void BspKey_DebugTestOnOff(uint8_t _uc_trueOrFalse, void *_vp_context)
{
    BSP_KEY_T_INTERFACE *tp_interface = _vp_context;
    if (tp_interface == NULL)
    {
        return;
    }
    if (_uc_trueOrFalse == true)
    {
        tp_interface->t_Private.uc_DebugTestEnable = 1;
    }
    else
    {
        tp_interface->t_Private.uc_DebugTestEnable = 0;
    }
}
/*********************************************************************************************************
      END FILE
*********************************************************************************************************/
